#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

//TCP连接的部分
#include "net_demo.h"
#include "net_common.h"

/*****机器人板上左右轮控制的部分*****/

extern void car_backward(void);
extern void car_forward(void);
extern void car_left(void);
extern void car_right(void);
extern void car_stop(void);

/*****************************************************************************************************************************************************************/ 

#define DELAY_1S  (1)

void TcpServerTest(unsigned short port)
{

/****************************************************************************************************/ 

    ssize_t retval = 0;
    int backlog = 1;
    int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
    int connfd = -1;

    struct sockaddr_in clientAddr = {0};
    socklen_t clientAddrLen = sizeof(clientAddr);
    struct sockaddr_in serverAddr = {0};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);  // 端口号，从主机字节序转为网络字节序
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 允许任意主机接入， 0.0.0.0

/*****************************************绑定端口****************************************************/

    retval = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); 
    if (retval < 0) {
        printf("_______________________________________\r\n");
        printf("bind failed, %ld!\r\n", retval);       
    }else{
    printf("_______________________________________\r\n");
    printf("bind to port %hu success!\r\n", port);
    }

/*****************************************开始监听***************************************************/

    retval = listen(sockfd, backlog); // 开始监听
    if (retval < 0) {
        printf("_______________________________________\r\n");
        printf("listen failed!\r\n");
    }else{
    printf("_______________________________________\r\n");
    printf("listen with %d backlog success!\r\n", backlog);
    }

/**************************************接受客户端连接*************************************************/

    while (1) {

    connfd = accept(sockfd, (struct sockaddr *)&clientAddr, &clientAddrLen);
    if (connfd < 0) {
        printf("accept failed, %d, %d\r\n", connfd, errno);
        continue;
    }else{
    printf("_______________________________________\r\n");
    printf("accept success, connfd = %d!\r\n", connfd);
    printf("client addr info: host = %s, port = %hu\r\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
    }

/***********************************socket收、发的部分************************************************/

       // 后续 收、发 都在 表示连接的 socket 上进行；
       while (1) {
       char request[128] = "";

       //3861接收数据
       retval = recv(connfd, request, sizeof(request), 0);
       if (retval < 0) {

           //3568侧断开与3861的tcp连接后进行的处理
           printf("_______________________________________\r\n");
           printf("recv request failed, %ld!\r\n", retval);
           printf("do_reconnect...\r\n");
           sleep(DELAY_1S);
           close(connfd);//关闭与客户端的连接
           sleep(DELAY_1S); // for debug
           
           break;//跳出while循环
           car_stop();//小车进入停止状态

        }else{
           printf("_______________________________________\r\n");
           printf("The data received from the client is %s \r\n", request);
        }

        //3861发送数据
        retval = send(connfd, request, strlen(request), 0);
        if (retval <= 0) {

           //3568侧断开与3861的tcp连接后进行的处理
           printf("_______________________________________\r\n");
           printf("send response failed, %ld!\r\n", retval);
           printf("do_reconnect...\r\n");
           sleep(DELAY_1S);
           close(connfd);//关闭与客户端的连接
           sleep(DELAY_1S); // for debug

           break;//跳出while循环
           car_stop();//小车进入停止状态

        }else{
           printf("The data responsed to the client is %s\r\n", request);
        }

/****************3568（tcp客户端）发送数据“01234”控制小车前进、后退、左转、右转************************/

        unsigned int g_car_status = 0; 

        // 将字符串request转换成int类型
        g_car_status=atoi(request);

	    switch (g_car_status)
	    {

          //接收到数据“0”，小车前进
	      case 0:
          printf("car_forward\n" );   
          car_forward();
          break;  

          //接收到数据“1”，小车后退
	      case 1:
          printf("car_backward\n" ); 
          car_backward();
          break;  

          //接收到数据“2”，小车左转
	      case 2:
          printf("car_left\n");
          car_left(); 
          break;	

          //接收到数据“3”，小车右转
	      case 3:
          printf("car_right\n");
          car_right();
          break;

          //接收到数据“4”,小车停止
	      case 4:
          printf("car_stop\n");
          car_stop();
          break;

	      default:
          break;   
        }

/*************************************************************************************************/

    }

    }

/*****************************************************************************************************************************************************************/ 
    close(sockfd); 
}

SERVER_TEST_DEMO(TcpServerTest);